import { stringify } from 'qs'
import { getNewPayload } from './_utils'
import type { TRequestConfig } from './data'
import http, { type TMethod } from './http'
import sendJsonp from './sendJsonp'

/**
 * @description 加固请求
 *
 * @param config 配置参数
 * @param reinforce 是否加固
 * */
export const colorReinforce = async <T>(config: TRequestConfig, reinforce?: boolean): Promise<T> => {
  const { functionId, params, data, method, appid, jsonp, jsonpOptions } = config
  const url = `xxx/api`
  let newParams = params || {}
  let newData = data || {}
  // 区分 get 和非 get 请求
  let _method: TMethod = 'GET'
  if (method) {
    _method = method === 'get' || method === 'GET' ? 'GET' : method
  }
  if (jsonp && _method !== 'GET') {
    _method = 'GET'
  }

  if (_method === 'GET') {
    newParams = await getNewPayload(appid, functionId, params, reinforce)
    if (jsonp) {
      // 兼容 jsonp
      return sendJsonp<T>(`${url}?${stringify(newParams)}`, jsonpOptions)
    }
  } else {
    if (params && data) {
      // 既携带 params 又携带 data
      const mergeParams = Object.assign({}, params, data)
      const mergePayload = await getNewPayload(appid, functionId, mergeParams, reinforce)
      const _params: any = {}
      const _data: any = {}
      for (const key in mergePayload) {
        if (params[key]) {
          _params[key] = mergePayload[key]
        }
        if (data[key]) {
          _data[key] = mergePayload[key]
        }
        // 加签参数默认放在 data 中
        if (!params[key] && !data[key]) {
          _data[key] = mergePayload[key]
        }
      }
      newParams = _params
      newData = _data
    } else if (params) {
      // 只携带 params
      newParams = await getNewPayload(appid, functionId, params, reinforce)
    } else if (data) {
      // 只携带 data
      newData = await getNewPayload(appid, functionId, data, reinforce)
    } else {
      // 都不携带 加签参数放在 data 中
      newParams = params
      newData = await getNewPayload(appid, functionId, data, reinforce)
    }
  }

  return http<any, T>({
    headers: {
      'Content-Type': '	application/x-www-form-urlencoded',
      ...config.headers,
    },
    url,
    method: _method,
    params: newParams,
    data: newData,
  })
}
